package com.sailors.common.task.sdk.core.handle.anno;

import com.sailors.common.task.sdk.core.handle.factory.FileTaskTemplateHandler;
import com.sailors.common.task.sdk.core.handle.factory.HandlerFactory;
import com.sailors.common.task.sdk.core.model.FileTaskAsyncUploadCreateDto;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;

@Aspect
@Component
@Slf4j
public class AsyncUploadFileTaskAspect {

    @Around("execution (@com.sailors.common.task.sdk.core.handle.anno.AsyncUploadFileTask  * *.*(..))")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        AsyncUploadFileTask asyncUploadFileTask = method.getAnnotation(AsyncUploadFileTask.class);

        String invokeAsyncUploadFileDtoMethod = asyncUploadFileTask.invokeAsyncUploadFileDtoMethod();
        int limit = asyncUploadFileTask.limit();
        log.info("AsyncUploadFileTaskAspect:{}, {}", invokeAsyncUploadFileDtoMethod, limit);

        Object target = pjp.getTarget();
        Class<?> clazz = pjp.getTarget().getClass();

        FileTaskAsyncUploadCreateDto fileTaskAsyncUploadCreateDto = (FileTaskAsyncUploadCreateDto) ReflectionUtils.invokeMethod(clazz.getMethod("instanceMethodWithReturn"), target, pjp.getArgs());

        // 创建任务中心任务
        FileTaskTemplateHandler fileTaskTemplateHandler = (FileTaskTemplateHandler) HandlerFactory.getInstance(FileTaskTemplateHandler.class);
        fileTaskTemplateHandler.executeAsyncUploadFileTask(fileTaskAsyncUploadCreateDto, () -> {
            try {
                pjp.proceed();
            } catch (Throwable throwable) {
                log.warn("executeAsyncUploadFileTask error: {}", throwable.getMessage());
            }
            return null;
        }, limit);
        return null;
    }
}
